package com.raincat.tools.multimediapickertools.utils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.raincat.tools.R;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;

/**
 * <pre>
 *     author : RainCat
 *     org    : Shenzhen JingYu Network Technology Co., Ltd.
 *     e-mail : nining377@gmail.com
 *     time   : 2019/02/25
 *     desc   : 多媒体控制类
 *     version: 1.0
 * </pre>
 */

public class MultiMediaController {
    //配置
    public static boolean isInit = false;
    /**
     * 压缩后图片最大尺寸（不建议更改）
     */
    private final static int MAXSIZE = 400;
    /**
     * 只查看图片
     */
    public static final int TAKE = 0;
    /**
     * 选择图片并裁剪
     */
    public static final int CROP = 1;
    /**
     * 混合选择
     */
    public static final int MIX = 2;
    /**
     * 选择视频
     */
    public static final int VIDEO = 3;
    /**
     * 模式：0.只选择图片 1.选择图片并裁剪，2.混合选择，3.选择视频
     */
    public static int mode = 0;
    /**
     * 主题ID
     */
    public static int themeId = 0;
    /**
     * 裁剪输出大小，默认300
     */
    public static int outputX = 300;
    public static int outputY = 300;
    /**
     * 图片选择数量，默认为1
     */
    public static int maxCount = 1;

    /**
     * 可选的单个图片或视频的最大容量
     */
    public static int imageMaxSize = 10 * 1024 * 1024;
    public static int videoMaxSize = 100 * 1024 * 1024;
    /**
     * 视频默认最大时长
     */
    public static long videoMaxDuration = 10 * 60 * 1000;
    /**
     * 是否显示拍照
     */
    public static boolean showCameraOption = false;
    /**
     * 是否显示原图
     */
    public static boolean showOriginalOption = false;
    /**
     * 是否显示GIF图
     */
    public static boolean showGif = true;
    /**
     * 黑色状态栏
     */
    public static boolean blackStatusBar = false;

    //数据
    //是否返回原图
    public static boolean isOriginal = false;
    // 对外开放的列表，一个压缩后图片路径集，一个原始图片路径集
    public static LinkedHashMap<String, MultiMediaItem> multiMediaItemMap = new LinkedHashMap<>();
    private static float imageSize = 0f;
    private static int imageIndex = 0;

    static void initController(PickerConfig pickerConfig) {
        isInit = true;
        mode = pickerConfig.mode;
        if (mode == CROP)
            maxCount = 1;
        else
            maxCount = pickerConfig.maxCount;
        themeId = pickerConfig.themeId;
        outputX = pickerConfig.outputX;
        outputY = pickerConfig.outputY;
        showCameraOption = pickerConfig.showCameraOption;
        showOriginalOption = pickerConfig.showOriginalOption;
        imageMaxSize = pickerConfig.imageMaxSize;
        videoMaxSize = pickerConfig.videoMaxSize;
        videoMaxDuration = pickerConfig.videoMaxDuration;
        showGif = pickerConfig.showGif;
        blackStatusBar = pickerConfig.blackStatusBar;

        if (pickerConfig.existingMultiMediaList != null) {
            int index = 1;
            for (MultiMediaItem multiMediaItem : pickerConfig.existingMultiMediaList) {
                multiMediaItem.index = index++;
                multiMediaItemMap.put(multiMediaItem.path, multiMediaItem);
            }
        }
    }

    /**
     * 把选中图片放入或移出临时Map
     *
     * @param context        context
     * @param multiMediaItem 图片对象
     * @return 添加返回true，移出返回false
     */
    public static boolean addOrRemoveMultiMediaItem(Context context, MultiMediaItem multiMediaItem) {
        boolean status = false;
        if (multiMediaItemMap.get(multiMediaItem.path) != null) {
            multiMediaItemMap.remove(multiMediaItem.path);
            if (multiMediaItem.mimeType.equals("image"))
                imageSize = imageSize - multiMediaItem.size;
        } else if (multiMediaItemMap.size() < maxCount) {
            if (multiMediaItem.size > imageMaxSize && multiMediaItem.mimeType.equals("image")) {
                Toast.makeText(context, String.format(context.getString(R.string.picker_select_tips2), imageMaxSize * 1.0f / 1024 / 1024 + "M"), Toast.LENGTH_SHORT).show();
            } else if (multiMediaItem.size > videoMaxSize && multiMediaItem.mimeType.equals("video")) {
                Toast.makeText(context, String.format(context.getString(R.string.picker_select_tips2), videoMaxSize * 1.0f / 1024 / 1024 + "M"), Toast.LENGTH_SHORT).show();
            } else if (multiMediaItem.durationStamp > videoMaxDuration && multiMediaItem.mimeType.equals("video")) {
                Toast.makeText(context, String.format(context.getString(R.string.picker_select_tips3), videoMaxDuration / 1000 + ""), Toast.LENGTH_SHORT).show();
            } else {
                multiMediaItemMap.put(multiMediaItem.path, multiMediaItem);
                if (multiMediaItem.mimeType.equals("image"))
                    imageSize = imageSize + multiMediaItem.size;
                status = true;
            }
        } else {
            Toast.makeText(context, String.format(context.getResources().getString(R.string.picker_select_tips1), maxCount), Toast.LENGTH_SHORT).show();
        }
        //  刷新索引
        int index = 1;
        for (MultiMediaItem item : multiMediaItemMap.values()) {
            item.index = index++;
        }
        return status;
    }

    /**
     * 根据path移除选中的图片
     *
     * @param context  context
     * @param path     图片路径
     * @param mimeType 多媒体类型
     */
    public static void addOrRemoveMultiMediaItem(Context context, String path, String mimeType) {
        MultiMediaItem multiMediaItem = new MultiMediaItem();
        multiMediaItem.path = path;
        multiMediaItem.size = ImageCacheUtils.getFileSize(path);
        multiMediaItem.mimeType = mimeType;
        addOrRemoveMultiMediaItem(context, multiMediaItem);
    }

    /**
     * 缩小图片集
     */
    private static void takeZoomPath(final Context context, final OnAllDecodeListener listener) {
        imageIndex = 0;
        final ProgressDialog dialog = ProgressDialog.show(context, null, context.getResources().getString(R.string.picker_now_loading_please_wait));
        final ImageCacheUtils imageCacheUtils = new ImageCacheUtils(context);
        for (MultiMediaItem multiMediaItem : multiMediaItemMap.values()) {
            decodeBitmap(context, multiMediaItem, new OnDecodeListener() {
                @Override
                public void onResult(String path, String zoomPath, Bitmap bm) {
                    if (bm != null) {
                        imageCacheUtils.addBitmapToFile(path, 80, bm);
                        multiMediaItemMap.get(path).zoomPath = imageCacheUtils.getCachePath(path);
                    } else
                        multiMediaItemMap.get(path).zoomPath = zoomPath;

                    imageIndex++;
                    if (imageIndex == multiMediaItemMap.size()) {
                        dialog.dismiss();
                        listener.onResult();
                    }
                }
            });
        }
    }

    private static synchronized void decodeBitmap(Context context, final MultiMediaItem imageItem, final OnDecodeListener b) {
        if (imageItem.suffix.equalsIgnoreCase("gif"))
            b.onResult(imageItem.path, imageItem.path, null);
        else if (imageItem.mimeType.equals("video"))
            b.onResult(imageItem.path, imageItem.path, null);
        else if (imageItem.zoomPath.length() != 0)
            b.onResult(imageItem.path, imageItem.zoomPath, null);
        else {
            try {
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(imageItem.path)));
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(in, null, options);
                in.close();

                int reqWidth, reqHeight;
                if (options.outHeight < options.outWidth) {
                    reqWidth = MAXSIZE;
                    reqHeight = MAXSIZE * options.outWidth / options.outHeight;
                } else {
                    reqHeight = MAXSIZE;
                    reqWidth = MAXSIZE * options.outHeight / options.outWidth;
                }

                if (context != null) {
                    if (((Activity) context).isFinishing())
                        return;
                    Glide.with(context).asBitmap().load(imageItem.path).into(new SimpleTarget<Bitmap>(reqWidth, reqHeight) {
                        @Override
                        public void onResourceReady(@NonNull Bitmap arg0, Transition<? super Bitmap> arg1) {
                            b.onResult(imageItem.path, null, arg0);
                        }
                    });
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public interface OnDecodeListener {
        void onResult(String path, String zoomPath, Bitmap bm);
    }

    public interface OnAllDecodeListener {
        void onResult();
    }

    /**
     * 实时统计图片大小
     */
    public static String getImageSize() {
        if (multiMediaItemMap.size() == 0)
            imageSize = 0;
        if (imageSize == 0)
            return "";
        else if (imageSize / 1024 < 1000)
            return "(" + String.format(Locale.getDefault(), "%.2f", imageSize / 1024) + "K)";
        else
            return "(" + String.format(Locale.getDefault(), "%.2f", imageSize / 1024 / 1024) + "M)";
    }

    /**
     * 根据选中的多媒体获取List
     */
    public static void getMultiMediaList(final Context context) {
        if (!isOriginal) {
            takeZoomPath(context, new OnAllDecodeListener() {
                @Override
                public void onResult() {
                    setResult(context);
                }
            });
        } else {
            for (MultiMediaItem multiMediaItem : multiMediaItemMap.values())
                multiMediaItem.zoomPath = multiMediaItem.path;
            setResult(context);
        }
    }

    private static void setResult(final Context context) {
        List<MultiMediaItem> multiMediaItemList = new ArrayList<>(multiMediaItemMap.values());
        PickerListenerManager.getInstance().onPicker(multiMediaItemList);
        finish(context);
    }

    public static void finish(final Context context) {
        PickerListenerManager.getInstance().onDestroy();
        ((Activity) context).finish();
        ((Activity) context).overridePendingTransition(0, R.anim.push_bottom_out);
        PickerConfig.reset();
    }

    static void reset() {
        if (multiMediaItemMap != null)
            multiMediaItemMap.clear();
        imageSize = 0.0F;
        imageIndex = 0;
        isOriginal = false;
        isInit = false;
    }
}
